/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package SnpDbEntities;

import SnpDbHandling.DBHndLogger;
import SnpDbHandling.UserPermissionsPolicy;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.regex.Pattern;

/**
 *
 * @author Łukasz 'byku' Guzik
 */
public class User implements Serializable
{
    private static class MaxLengths
    {
	private static final int MAX_LOGIN_LENGTH = 30;
	private static final int MAX_NAME_LENGTH = 100;
	private static final int MAX_EMAIL_LENGTH = 100;
	private static final int MAX_ABOUT_LENGTH = 200;
    }
    private int id;
    private String login;
    private String pwdHash;
    private UserPermissions permissions;
    private boolean isEnabled;
    private String name;
    private String email;
    private String about;
    private UserPermissionsPolicy userPermissionsPolicy = null;

    public int getId()
    {
	return id;
    }

    public void setId(int id)
    {
	this.id = id;
    }

    public String getLogin()
    {
	return login;
    }

    public void setLogin(String login)
    {
	if(login.length() > MaxLengths.MAX_LOGIN_LENGTH)
	{
	    throw new IllegalArgumentException();
	}
	this.login = login;
    }

    public String getPwdHash()
    {
	return pwdHash;
    }

    public void setPwdHash(String pwdHash)
    {
	this.pwdHash = pwdHash;
    }

    public UserPermissions getPermissions()
    {
	return permissions;
    }

    public void setPermissions(UserPermissions permissions)
    {
	this.permissions = permissions;
	userPermissionsPolicy = UserPermissionsPolicy.getInstance(this);
    }

    public boolean isEnabled()
    {
	return isEnabled;
    }

    public void setEnabled(boolean isEnabled)
    {
	this.isEnabled = isEnabled;
    }

    public String getName()
    {
	return name;
    }

    public void setName(String name)
    {
	if(name.length() > MaxLengths.MAX_NAME_LENGTH)
	{
	    throw new IllegalArgumentException();
	}
	this.name = name;
    }

    public String getEmail()
    {
	return email;
    }

    public void setEmail(String email)
    {
	if(validateEmail(email))
	    this.email = email;
	else
	    throw new IllegalArgumentException();
    }

    public String getAbout()
    {
	return about;
    }

    public void setAbout(String about)
    {
	if(about != null && about.length() > MaxLengths.MAX_ABOUT_LENGTH)
	{
	    throw new IllegalArgumentException();
	}
	this.about = about;
    }

    public static String calculateSHA1(String in)
    {
	try
	{
	    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
	    byte[] shaHash = sha1.digest(in.getBytes());
	    Formatter formatter = new Formatter();
	    for(byte b : shaHash)
	    {
		formatter.format("%02x", b);
	    }
	    return formatter.toString();
	} catch(NoSuchAlgorithmException e)
	{
	    DBHndLogger.logException(Level.SEVERE, e);
	    return null;
	}
    }

    private static boolean validateEmail(String email)
    {
	if(email.length() > MaxLengths.MAX_EMAIL_LENGTH)
	    return false;

	boolean matches = Pattern.matches(".+@.+\\.[a-z]+", email);
	StringTokenizer st = new StringTokenizer(email, ".");
	String lastToken = null;

	while(st.hasMoreTokens())
	    lastToken = st.nextToken();

	if(matches && lastToken.length() >= 2)
	    return true;
	else
	    return false;
    }

    public void annonimizeSensibleData(final User userWhoWantsData)
    {
	setPwdHash("0");

	if(userWhoWantsData.getId() != this.getId()
		&& userWhoWantsData.getPermissions() == UserPermissions.NORMAL_USER
		&& this.getPermissions() == UserPermissions.NORMAL_USER)
	    setEmail("hidden@hidden.hid");
    }

    public boolean canUpdateUser(User userToUpdate, User newUserData)
    {
	if(userPermissionsPolicy == null)
	    return false;

	return userPermissionsPolicy.canUpdateUser(userToUpdate, newUserData);
    }

    public boolean canDisEnableUser(User userToDisEnable)
    {
	if(userPermissionsPolicy == null)
	    return false;

	return userPermissionsPolicy.canDisEnableUser(userToDisEnable);
    }

    public boolean canDeleteUser(User userToDelete)
    {
	if(userPermissionsPolicy == null)
	    return false;

	return userPermissionsPolicy.canDeleteUser(userToDelete);
    }

    public boolean canAddUser(User userToAdd)
    {
	if(userPermissionsPolicy == null)
	    return false;

	return userPermissionsPolicy.canAddUser(userToAdd);
    }

    public boolean canChangePublicCategories()
    {
	if(userPermissionsPolicy == null)
	    return false;
	
	return userPermissionsPolicy.canChangePublicCategories();
    }

    public boolean canUpdatePublicSnippet()
    {
	if(userPermissionsPolicy == null)
	    return false;
	
	return userPermissionsPolicy.canUpdatePublicSnippet();
    }

    @Override
    public String toString()
    {
	return name + " [" + login + "]";
    }
}
